package org.bookie.web.pages.account;

import java.util.List;

import org.apache.tapestry.IAsset;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.annotations.Asset;
import org.apache.tapestry.event.PageBeginRenderListener;
import org.apache.tapestry.event.PageEvent;
import org.bookie.framework.CommonBasePage;
import org.bookie.framework.components.PeriodComponent;
import org.bookie.model.BetSlip;
import org.bookie.model.IBetSlip;
import org.bookie.model.Role;
import org.bookie.model.SingleBetSlip;
import org.bookie.model.User;
import org.bookie.model.security.Access;
import org.bookie.model.services.BetSlipDAO;
import org.bookie.model.services.UserDAO;

@Access(role=Role.USER)
public abstract class BetSlipList extends CommonBasePage implements PageBeginRenderListener{
	
	/**Identifier of the client component containing the detail view of a {@link BetSlip}.*/
	public static final String DETAILS = "details";
	/**Identifier of the client component containing the period component.*/
	public static final String PERIOD = "period";
	/**
	 * @see org.apache.tapestry.event.PageBeginRenderListener#pageBeginRender(org.apache.tapestry.event.PageEvent)
	 */
	public void pageBeginRender(PageEvent event) {
		User user = getUserDAO().findByEmail(
				getAuthenticationContext().getUser().getEmail());
		PeriodComponent period = (PeriodComponent) getComponent(BetSlipList.PERIOD);
		setBetSlips(getBetSlipDAO().findByUser(user, period.getPeriod()));
	}
	
	/**
	 * Listener method to select a {@link BetSlip} for a detailed view.
	 * @param id identifier of the BetSlip to select
	 */
	public void selectBetSlip(Long id){
		BetSlip betSlip = getBetSlipDAO().findById(id);
		if(betSlip==null){
			return;
		}
		select(betSlip);
	}
	
	/**
	 * Listener method to hide the detailed view of a {@link BetSlip}.
	 */
	public void deleteBetSlip(){
		select(null);
	}
	
	/**
	 * Get the localized status of a {@link BetSlip}.
	 * @param betSlip BetSlip to get localized status of
	 * @return localized string
	 */
	public String getType(BetSlip betSlip){
		if(betSlip instanceof SingleBetSlip){
			return getMessages().getMessage("betslipList.betslip.type.single");
		}
		return getMessages().getMessage("betslipList.betslip.type.multiple");
	}
	
	/**
	 * Get the icon {@link IAsset} for a {@link BetSlip}.
	 * This icon visualizes the state of the bet slip.
	 * @param betSlip BetSlip to get the IAsset
	 * @return instance of IAsset
	 */
	public IAsset getStateAsset(IBetSlip betSlip){
		if(betSlip.isClosed()){
			return betSlip.getBalance().doubleValue()<0?getMinusIcon():getPlusIcon();
		}
		return getWaitingIcon();
	}
	
	/**
	 * Selects a {@link BetSlip} for a detailed view and updates the client component.
	 * @param betSlip BetSlip to select
	 */
	private void select(BetSlip betSlip){
		setSelectedBetSlip(betSlip);
		IComponent details = getComponent(DETAILS);
		getResponseBuilder().updateComponent(details.getId());
	}
	
	/**Injected plus icon {@link IAsset}*/
	@Asset("images/coins_plus.png")
	public abstract IAsset getPlusIcon();
	
	/**Injected minus icon {@link IAsset}*/
	@Asset("images/coins_minus.png")
	public abstract IAsset getMinusIcon();
	
	/**Injected waiting icon {@link IAsset}*/
	@Asset("images/hourglass.png")
	public abstract IAsset getWaitingIcon();
	
	/**
	 * Injected User service.
	 * @return instance of UserDAO
	 */
	public abstract UserDAO getUserDAO();
	
	/**
	 * Injected BetSlip service.
	 * @return instance of BetSlipDAO
	 */
	public abstract BetSlipDAO getBetSlipDAO();
	
	/**
	 * Get the {@link BetSlip}s of the authenticated user.
	 * @return a list of BetSlip
	 */
	public abstract List getBetSlips();
	
	/**
	 * Set the {@link BetSlip}s of the authenticated user.
	 * @param betSlips list of BetSlip to set
	 */
	public abstract void setBetSlips(List betSlips);
	
	/**
	 * Set the current bet slip of the iteration over all {@link BetSlip}s
	 * @param betSlip
	 */
	public abstract void setCurrentBetSlip(BetSlip betSlip);
	
	/**
	 * Set the {@link BetSlip} for detailed view.
	 * @param betSlip BetSlip to set
	 */
	public abstract void setSelectedBetSlip(BetSlip betSlip);
}
